﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using DapperExtensions;

namespace IDal
{
    /// <summary>
    /// Dal接口（定义T类型实体的Dal功能，只负责对T类型的实体的数据操作）sql语句版+linq语句版+lambda表达式版
    /// </summary>
    public interface IBaseDal<T> where T:class,new()
    {

        #region 增加
        /// <summary>
        /// 增加一条记录
        /// </summary>
        /// <param name="entity">实体</param>
        void Add(T entity);
        /// <summary>
        /// 批量增加
        /// </summary>
        /// <param name="entityList">实体集合</param>
        void Add(List<T> entityList);
        #endregion

        #region 删除
        /// <summary>
        /// 删除一条记录
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>操作成功与否</returns>
        bool Delete(T entity);
        /// <summary>
        /// 条件删除（DapperExtensions）
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns>操作成功与否</returns>
        bool Delete(IPredicate predicate);
        //bool Delete(Expression<Func<T, bool>> whereLambda);
        #endregion

        #region 修改
        /// <summary>
        /// 更新一条记录
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>操作成功与否</returns>
        bool Update(T entity);
        //bool Update(List<T> entityList);
        #endregion

        #region 查询
        /// <summary>
        /// 主键查询
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>实体</returns>
        T Get(object id);
        /// <summary>
        /// 带参数的sql查询
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameter">实体参数</param>
        /// <returns>实体</returns>
        T Get(string sql, T parameter);
        /// <summary>
        /// 条件查询（DapperExtensions）
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns>实体</returns>
        T Get(IPredicate predicate);
        //T GetEntity(IQueryable<T> linq);
        //T GetEntity(Expression<Func<T, bool>> whereLambda);
        /// <summary>
        /// sql查询记录数
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns>记录数</returns>
        int GetCount(string sql);
        /// <summary>
        /// 带参数的sql查询记录数
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameter">实体参数</param>
        /// <returns>记录数</returns>
        int GetCount(string sql, T parameter);
        /// <summary>
        /// 条件查询记录数（DapperExtensions）
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns>记录数</returns>
        int GetCount(IPredicate predicate=null);
        //int GetSelectCount(IQueryable<T> linq);
        //int GetSelectCount(Expression<Func<T, bool>> whereLambda);
        /// <summary>
        /// 查询所有记录
        /// </summary>
        /// <returns>集合</returns>
        List<T> GetList();
        /// <summary>
        /// sql查询集合
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns>集合</returns>
        List<T> GetList(string sql);
        /// <summary>
        /// 带参数的sql查询集合
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameter">实体参数</param>
        /// <returns>集合</returns>
        List<T> GetList(string sql, T parameter);
        /// <summary>
        /// 条件查询集合（DapperExtensions）
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <param name="sort">排序</param>
        /// <returns>集合</returns>
        List<T> GetList(IPredicate predicate, IList<ISort> sort = null);
        //List<T> GetList(IQueryable<T> linq);//这边的这个linq看似没有意义，其实Bll层写的代码，即使在Bll层调用ToList(),看似Bll执行了数据操作权，其实真正的操作还是在Dal层。这里写这个接口只是为了给开发人员一种更直观的展示。（“假调用”）
        //List<T> GetList(Expression<Func<T, bool>> whereLambda);//lambda语句查询的方法，返回值最好是IQueryable，不然不容易扩展查询,这里还要AsQueryable才能扩展，多此一举。
        /// <summary>
        /// sql分页查询
        /// </summary>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="total">总记录数</param>
        /// <param name="sql">sql语句</param>
        /// <param name="orderBy">排序</param>
        /// <returns>集合</returns>
        List<T> GetListByPage(int pageSize, int pageIndex, out int total, string sql,string orderBy);
        /// <summary>
        /// 带参数的sql分页查询
        /// </summary>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="total">总记录数</param>
        /// <param name="sql">sql语句</param>
        /// <param name="parameter">实体参数</param>
        /// <param name="orderBy">排序</param>
        /// <returns>集合</returns>
        List<T> GetListByPage(int pageSize, int pageIndex, out int total, string sql,T parameter,string orderBy);
        /// <summary>
        /// 条件分页查询（DapperExtensions）
        /// </summary>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="total">总记录数</param>
        /// <param name="predicate">条件</param>
        /// <param name="sort">排序</param>
        /// <returns>集合</returns>
        List<T> GetListByPage(int pageSize, int pageIndex, out int total, IPredicate predicate, IList<ISort> sort);
        //List<T> GetListByPage(int pageSize,int pageIndex,out int total,IQueryable<T> linq);
        //List<T> GetListByPage(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda);//默认排序(a=>""可能生成的sql脚本效率不高)
        //List<T> GetListByPage<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, bool isAsc);//自定义默认排序
        //IQueryable<T> GetIQueryable();
        //IQueryable<T> GetIQueryable(string sql);
        //IQueryable<T> GetIQueryable(string sql,DbParameter[] dbParameter);
        //IQueryable<T> GetIQueryable(IQueryable<T> linq);
        //IQueryable<T> GetIQueryable(Expression<Func<T, bool>> whereLambda);
        //IQueryable<T> GetIQueryableByPage(int pageSize, int pageIndex, out int total, string sql);
        //IQueryable<T> GetIQueryableByPage(int pageSize, int pageIndex, out int total, string sql, DbParameter[] dbParameter);
        //IQueryable<T> GetIQueryableByPage(int pageSize, int pageIndex, out int total, IQueryable<T> linq);
        //IQueryable<T> GetIQueryableByPage(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda);
        //IQueryable<T> GetIQueryableByPage<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, bool isAsc);
        #endregion

    }
}
